﻿using Circus.Utility;
using System;
using System.Collections.Generic;

namespace Teal.Club {

    /// <summary>
    /// 提供分类相关接口。
    /// </summary>
    public static class CategoryController {

        /// <summary>
        /// 添加一个分类。
        /// </summary>
        /// <param name="parentId">上级分类序号。如果是顶级分类则为 0。</param>
        /// <param name="name">分类名。</param>
        /// <returns>返回添加的分类序号，如果添加失败则返回 0。</returns>
        public static object add(int parentId, string name) {
            UserController.checkLogin(UserRole.admin);
            using (var conn = DbHelper.createConnection()) {
                var cmd = conn.createProcedure("category_add");
                cmd.Parameters.AddWithValue("@parentId", parentId);
                cmd.Parameters.AddWithValue("@name", name);
                var id = cmd.ExecuteScalar();
                return new {
                    code = 0,
                    id = id
                };
            }
        }

        /// <summary>
        /// 删除评论。
        /// </summary>
        /// <param name="id">要删除的评论序号。</param>
        /// <returns>如果操作成功返回空字符串，否则返回错误原因。</returns>
        public static object delete(int id) {
            UserController.checkLogin(UserRole.admin);
            using (var conn = DbHelper.createConnection()) {
                var cmd = conn.createProcedure("category_delete");
                cmd.Parameters.AddWithValue("@id", id);
                if (cmd.ExecuteNonQuery() > 0) {
                    _categories.Clear();
                    return new {
                        code = 0
                    };
                }
                return new {
                    code = 1,
                    msg = "分类不存在或已删除"
                };
            }
        }

        /// <summary>
        /// 更新评论。
        /// </summary>
        /// <param name="id">要更新的评论序号。</param>
        /// <param name="name">要更新的分类名。</param>
        /// <returns>如果操作成功返回空字符串，否则返回错误原因。</returns>
        public static object update(int id, string name) {
            UserController.checkLogin(UserRole.admin);
            using (var conn = DbHelper.createConnection()) {
                var cmd = conn.createProcedure("category_update");
                cmd.Parameters.AddWithValue("@id", id);
                cmd.Parameters.AddWithValue("@name", name);
                if (cmd.ExecuteNonQuery() > 0) {
                    _categories.Clear();
                    return new {
                        code = 0
                    };
                }
                return new {
                    code = 1,
                    msg = "分类不存在或已删除"
                };
            }
        }

        private static Dictionary<int, CategoryInfo> _categories = new Dictionary<int, CategoryInfo>();

        /// <summary>
        /// 表示一个分类信息。
        /// </summary>
        private struct CategoryInfo {

            /// <summary>
            /// 获取当前分类的父级。
            /// </summary>
            public int parentId;

            /// <summary>
            /// 获取当前分类的名字。
            /// </summary>
            public string name;

            /// <summary>
            /// 获取当前分类的名字列表。
            /// </summary>
            public string[] names;

            public override string ToString() {
                return name;
            }

        }

        private static CategoryInfo get(int id) {

            CategoryInfo ci;

            if (_categories.TryGetValue(id, out ci)) {
                return ci;
            }

            using (var conn = DbHelper.createConnection()) {
                var cmd = conn.createProcedure("category_get");
                cmd.Parameters.AddWithValue("@id", id);
                var reader = cmd.ExecuteReader();
                if (reader.Read()) {
                    ci.parentId = reader.getInt("parentId");
                    ci.name = reader.getString("name");
                    return ci;
                }
            }
            return default(CategoryInfo);
        }

        /// <summary>
        /// 获取一个分类及父分类的名字。
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        internal static string[] getNames(int id) {
            CategoryInfo ci = get(id);
            if (ci.names == null) {
                if (ci.parentId != 0) {
                    var parentNames = getNames(ci.parentId);
                    ci.names = new string[parentNames.Length + 1];
                    Array.Copy(parentNames, ci.names, parentNames.Length);
                    ci.names[parentNames.Length] = ci.name;
                } else {
                    ci.names = new string[1] {
                        ci.name
                    };
                }
            }
            return ci.names;
        }

    }

}